package cx.mybatis.bingding;

import cn.hutool.core.lang.ClassScanner;
import cx.mybatis.session.SqlSession;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 注册接口和代理工厂
 * 目标:包装接口 提供代理类
 * @Author:cxy
 * @Date:2022/4/9 10:56
 */
public class MapperRegistry {

//    private Configuration configuration;

    // 接口类 : 代理工厂
    private final Map<Class<?>,MapperProxyFactory<?>> knownsMappers = new HashMap<>();

//    public MapperRegistry(Configuration configuration) {
//        this.configuration = configuration;
//    }

    @SuppressWarnings("unchecked")
    public <T> T getMapper(Class<T> type, SqlSession sqlSession){
        MapperProxyFactory<?> mapperProxyFactory = knownsMappers.get(type);
        if(mapperProxyFactory == null){
            throw new RuntimeException("Type " + type + " is not known to the MapperRegistry.");
        }
        return (T) mapperProxyFactory.newInstance(sqlSession);
    }

    public <T> void addMapper(Class<T> type){
        if(type.isInterface()){
            if(hasMapper(type)){
                // 如果重复添加了，报错
                throw new RuntimeException("Type " + type + " is already known to the MapperRegistry.");
            }
            knownsMappers.put(type,new MapperProxyFactory<>(type));
        }
    }

    private boolean hasMapper(Class<?> type){
        return knownsMappers.containsKey(type);
    }

    public void addMappers(String path){
        // 实例化Reflections，并指定要扫描的包名 可根据注解或者父类限定
//        Reflections reflections = new Reflections(path);
//        Set<String> types = reflections.getTypesAnnotatedWith(null);
        Set<Class<?>> classes = ClassScanner.scanPackage(path);
        for (Class<?> aClass : classes) {
            addMapper(aClass);
        }
    }
}
